<?php
class ArctypeModel extends CommonModel{
    //自动验证定义
    protected $_validate=array(
        array('name','require','请填写分类名',1),
        array('channelid','number','请选择频道模型'),
        array('pid','number','请选择上级栏目'),
        array('alias','require','别名必须填写',1),
        array('alias','_CheckAliasRule','别名不合法',1,'callback'),
        array('alias','_CheckAliasUsed','别名其他分类重复',1,'callback'),
    );
    //自动完成定义
    protected $_auto=array(
        
    );
    
    //检测分类别名是否合法
    function _CheckAliasRule($data){
        if(!empty($data)){
            if(!preg_match('/^[a-z0-9]+$/is',$data)){
                return false;
            }
        }
        return true;
    }
    //检测分类别名是否重复
    function _CheckAliasUsed($data) {
        if(empty($data)){
            return true;
        }
        $where=array(
            'alias' => $data
        );
        $typeid=I('post.id',0);
        if(is_numeric($typeid)){
            $where['id']=array('neq',$typeid);
        }
        //检查是否已经被其他分类使用
        $re = $this->field('alias')->where($where)->find();
        if ($re) {
            return false;
        }
        return true;
    }
    
    /**
     * 获取可移动分类options数组
     * @param int $exclude 排除的分类
     */
    function GetMoveOptions($exclude=0,$channelid=0){
        $where=array();
        if($channelid>0){
            $where['channelid']=$channelid;
        }
        $tree = new tree($this->field(TRUE)->where($where)->select());
        if(!empty($tree->tree) && $exclude>0){
            $this->_excludetype($tree->tree,$exclude);
        }
        return $tree->tree;
    }
    
    private function _excludetype(&$arr,$pid){
        foreach($arr as $k=>$v){
            if($v['pid']==$pid){
                $this->_excludetype($arr, $k);
                unset($arr[$k]);
            }
        }
        unset($arr[$pid]);
    }
    
    /**
     * 读取一个分类下的子分类和频道信息，用于删除分类
     * @param int $pid 父分类id
     */
    private function _getcTypes($pid) {
        static $count = 0; //递归次数
        $count++;
        if ($count > 1000) {
            return; //超过一千次递归则直接返回，防止死循环
        }
        $cids = array();//子分类信息
        $dbprefix=C("DB_PREFIX");//表前缀
        $re=$this->query("select a.id,a.channelid,c.addtable from {$dbprefix}arctype as a left join {$dbprefix}channel as c on c.id=a.channelid where a.id='{$pid}'");
        if(!empty($re)){
            $cids[] = $re[0];
        }
        $re1 = $this->field("id")->where(array("pid" => $pid))->select(); //读取子分类
        if (!empty($re1)) {
            foreach ($re1 as $v) {
                $cids = array_merge($cids,$this->_getcTypes($v["id"]));
            }
        }
        return $cids;
    }
    
    /**
     * 彻底删除一个分类及其子分类的关联信息
     * @param int $typeid 需要删除的分类id
     */
    function delType($typeid){
        (array)$cids=$this->_getcTypes($typeid);//获取自身以及所有子分类id
        $dbprefix=C("DB_PREFIX");
        foreach($cids as $eid){
            $this->startTrans();//开启事务
            //删除文章主表,附加表记录
            $re=$this->execute("delete a,b from {$dbprefix}arctiny as a left join {$eid['addtable']} as b on b.aid=a.id where a.typeid={$eid['id']}");
            if($re===FALSE){
                $this->rollback();//回滚事务
                return FALSE;
            }
            //删除分类表记录
            $re=$this->execute("delete from {$dbprefix}arctype where id='{$eid['id']}'");
            if($re===FALSE){
                $this->rollback();//回滚事务
                return FALSE;
            }
            //删除tags记录
            $re=$this->execute("delete from {$dbprefix}arctag where typeid='{$eid['id']}'");
            if($re===FALSE){
                $this->rollback();//回滚事务
                return FALSE;
            }
            $this->commit();
        }
        return true;
    }
}
